package com.ht.module.bus.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ht.config.dataAuth.DataScope;
import com.ht.constant.BusConstant;
import com.ht.constant.DicConstants;
import com.ht.module.bus.entity.*;
import com.ht.module.bus.mapper.TSchoolMapper;
import com.ht.module.bus.mapper.TStationMapper;
import com.ht.module.bus.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ht.module.bus.vo.SchoolTripVo;
import com.ht.module.bus.vo.StationToNumberVo;
import com.ht.module.sys.entity.SysDictItem;
import com.ht.module.sys.service.ISysDictService;
import com.ht.util.CommMethod;
import com.ht.util.Pager;
import com.ht.util.UserUtil;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 学校信息表 服务实现类
 * </p>
 *
 * @author hejialun
 * @since 2024-07-29
 */
@Service
public class TSchoolServiceImpl extends ServiceImpl<TSchoolMapper, TSchool> implements TSchoolService {
    @Resource
    private TStationService stationService;
    @Resource
    private TDistrictService districtService;
    @Resource
    private TRouteService routeService;
    @Resource
    private TClassService classService;
    @Resource
    private ISysDictService sysDictService;


    @Override
    public Pager<TSchool> findPage(Pager<TSchool> pager, TSchool en) {
        QueryWrapper<TSchool> qw = getQW(en);
        return baseMapper.findPageAuth(pager, qw, null);
    }

    @Override
    public List<TSchool> findList(TSchool en) {
        QueryWrapper<TSchool> qw = getQW(en);
        qw.eq("state", DicConstants.State.ENABLE);
        return baseMapper.findListAuth(qw, null);
    }

    @Override
    public List<SchoolTripVo> findTripList(TSchool en) {
        QueryWrapper<TSchool> qw = getQW(en);
        qw.eq("state", DicConstants.State.ENABLE);
        List<SchoolTripVo> tripList = baseMapper.findTripList(qw);
        return tripList;
    }

    @Override
    public void add(TSchool en) {
        //判断是否生成站点
        if (StrUtil.equals(en.getIsCreateStation(), DicConstants.State.ENABLE)) {
            TStation tStation = new TStation()
                    .setStationName(en.getSchoolName())
                    .setDistrictCode(en.getDistrictCode())
                    .setDescription(en.getSchoolName() + "对应站点");
            CommMethod.beanCreate(tStation);
            stationService.add(tStation);
            en.setStationCode(tStation.getStationCode());
        }
        baseMapper.insert(en);
    }

    @Override
    public Pager<StationToNumberVo> findStationToNumber(Pager<StationToNumberVo> pager, TSchool en) {
        QueryWrapper<TSchool> qw = getQW(en);
        qw.eq("state", DicConstants.State.ENABLE);
        //查询出所有路线
        List<TRoute> routes = routeService.list(
                new QueryWrapper<TRoute>()
                        .eq("state", DicConstants.State.ENABLE)
        );
        //获取所有被用了的路线id

        HashSet<String> stationCodes = new HashSet<>();
        for (TRoute route : routes) {
            stationCodes.add(route.getStationCodeStart());
            stationCodes.add(route.getStationCodeEnd());
            //分隔途经点
            stationCodes.addAll(Arrays.asList(route.getPassingPoindCode().split(",")));
        }
        if (!stationCodes.isEmpty()) {
            qw.notIn("station_code", stationCodes);
        }


        baseMapper.findStationToNumber(pager, qw);
        handleData(pager.getRecords());
        return pager;
    }

    @Override
    public List<Tree<String>> findDistrictSchoolClassTree() {
        TDistrict tDistrict = new TDistrict().setState("01");
        //获取当前用户所在区划
        //查询出区划树
        List<Tree<String>> sonTree = districtService.findTree(tDistrict, UserUtil.getDistrictCode());
        //查询出当前级别的区划
        TDistrict  current= districtService.getById(UserUtil.getDistrictCode());

        Tree<String> currentTree = new Tree<>();
        currentTree.setId(current.getDistrictCode());
        currentTree.setName(current.getDistrictName());
        currentTree.setParentId(current.getParentDistrictCode());
        CommMethod.initExtra(current, currentTree);


        currentTree.setChildren(sonTree);
        //叠加本机区划
        List<Tree<String>> districtTree=new ArrayList<>();
        districtTree.add(currentTree);

        //查询出学校年级班级数据
        List<TSchool> schools = this.findSchoolClassTree();


        for (Tree<String> tree : districtTree) {
            tree.put("type", "districtCode");
            if (BeanUtil.isEmpty(tree.getChildren())) {
                tree.setChildren(new ArrayList<>());
            }
            tree.getChildren().addAll(
                    schools.stream()
                            .filter(x -> StrUtil.equals(x.getDistrictCode(), tree.getId()))
                            .map(x -> {
                                Tree<String> node = new Tree<>();
                                node.setName(x.getSchoolName());
                                node.setId(x.getSchoolCode());
                                node.setChildren(x.getChildren());
                                CommMethod.initExtra(x, node);
                                return node;
                            })
                            .collect(Collectors.toList())
            );

            traverseDistrictTree(tree.getChildren(), schools);
        }

        return districtTree;
    }

    @Override
    public List<TSchool> findSchoolClassTree() {
        //查询出所有学校
        List<TSchool> schools = findList(new TSchool());
        //查询出所有班级
        List<TClass> classes = classService.findList(new TClass());
        classService.setGrade(classes);     //设置年级
        //移除已经毕业的
        classes = classes.stream().filter(x -> !StrUtil.equals(x.getGrade(), "已毕业")).collect(Collectors.toList());

        //构建年级节点
        for (TSchool school : schools) {
            school.setType("schoolCode");
            school.setId(school.getSchoolCode());
            school.setName(school.getSchoolName());
            //获取当前学校下的所有班级
            List<TClass> classNodes = classes.stream()
                    .filter(x -> StrUtil.equals(x.getSchoolCode(), school.getSchoolCode()))
                    .collect(Collectors.toList());

            //按年级分组
            Map<String, List<TClass>> gradeMap = classNodes.stream().collect(Collectors.groupingBy(TClass::getGrade));
            //构建年级节点
            for (String grade : gradeMap.keySet()) {
                Tree<String> node = new Tree<>();
                node.setName(grade);
                //班级id=学校id+班级名称
                node.setId(school.getSchoolCode() + "," + grade);
                node.put("type", "gradeCode");
                node.setChildren(
                        gradeMap.get(grade).stream().map(x -> {
                            Tree<String> sonNode = new Tree<>();
                            sonNode.setName(x.getClassName());
                            sonNode.setId(x.getClassCode());
                            sonNode.put("type", "classCode");
                            CommMethod.initExtra(x, sonNode);
                            return sonNode;
                        }).collect(Collectors.toList())
                );
                school.getChildren().add(node);
            }
        }

        return schools;

    }


    /**
     * 遍历区划树，构建学校数据
     *
     * @param children
     * @param schools
     */
    private void traverseDistrictTree(List<Tree<String>> children, List<TSchool> schools) {
        if (BeanUtil.isEmpty(children) || children.isEmpty()) {
            return;
        }
        // 递归遍历子节点
        for (Tree<String> tree : children) {
            if (BeanUtil.isEmpty(tree.get("type"))) {
                tree.put("type", "districtCode");
            }
            if (!StrUtil.equals(tree.get("type") + "", "districtCode")) {
                return;
            }
            if (BeanUtil.isEmpty(tree.getChildren())) {
                tree.setChildren(new ArrayList<>());
            }
            tree.getChildren().addAll(
                    schools.stream()
                            .filter(x -> StrUtil.equals(x.getDistrictCode(), tree.getId()))
                            .map(x -> {
                                Tree<String> node = new Tree<>();
                                node.setName(x.getSchoolName());
                                node.setId(x.getSchoolCode());
                                node.setChildren(x.getChildren());
                                CommMethod.initExtra(x, node);
                                return node;
                            })
                            .collect(Collectors.toList())
            );
            traverseDistrictTree(tree.getChildren(), schools);
        }
    }


    /**
     * 处理数据
     *
     * @param records
     */
    private void handleData(List<StationToNumberVo> records) {
        //查询出所有站点
        List<TStation> stations = stationService.list(
                new QueryWrapper<>()
        );
        //查询出所有区划
        List<TDistrict> districts = districtService.list(
                new QueryWrapper<>()
        );

        for (StationToNumberVo vo : records) {
            //过滤出学校对应站点
            TStation schoolStation = stations.stream().filter(x -> StrUtil.equals(x.getStationCode(), vo.getSchoolStationCode())).findFirst().orElse(null);
            if (schoolStation != null) {
                vo.setSchoolStationName(schoolStation.getStationName());
            }
            //过滤出站点对应区划
            TDistrict tDistrict = districts.stream().filter(x -> StrUtil.equals(x.getDistrictCode(), vo.getStationDistrictCode())).findFirst().orElse(null);
            if (tDistrict != null) {
                vo.setStationDistrictName(tDistrict.getDistrictName());
            }

            //找出当前学生上车点
            TStation studentStation = stations.stream().filter(x -> StrUtil.equals(x.getStationCode(), vo.getStationCode())).findFirst().orElse(null);
            if (studentStation != null) {
                vo.setStationName(studentStation.getStationName());
                vo.setStationDistrictCode(studentStation.getDistrictCode());
                //找到当前学生上车点对应的区划
                tDistrict = districts.stream().filter(x -> StrUtil.equals(x.getDistrictCode(), vo.getStationDistrictCode())).findFirst().orElse(null);
                if (tDistrict != null) {
                    vo.setStationDistrictName(tDistrict.getDistrictName());
                }
            }

        }


    }

    @Override
    public Pager<TSchool> findPageAuth(Pager<TSchool> pager, TSchool en) {
        QueryWrapper<TSchool> qw = getQW(en);
        return baseMapper.findPageAuth(pager, qw, new DataScope().initOrder(pager));
    }

    @Override
    public List<TSchool> findListAuth(TSchool en) {
        QueryWrapper<TSchool> qw = getQW(en);
        return baseMapper.findListAuth(qw, new DataScope());
    }


    private QueryWrapper<TSchool> getQW(TSchool en) {
        QueryWrapper<TSchool> qw = new QueryWrapper<>();
        if (StrUtil.isNotBlank(en.getSchoolName())) {
            qw.like("school_name", en.getSchoolName());
        }

        if (StrUtil.isNotEmpty(en.getDistrictCode())) {
            List<String> son = districtService.getSonList(en.getDistrictCode());
            son.add(en.getDistrictCode());
            qw.in("district_code", son);
        }

        if (StrUtil.isNotEmpty(en.getEducationStateName())) {
            qw.eq("education_state_name", en.getEducationStateName());
        }

        if (StrUtil.isNotEmpty(en.getState())) {
            qw.eq("state", en.getState());
        }
        qw.eq("del_flag", BusConstant.DEL_FLAG_N);
        qw.orderByDesc("create_date");
        return qw;
    }
}
